1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| #include <cstdio> #include <algorithm> #define LL long long #define int long long const int maxn = 5e4 + 5; using namespace std; struct E{ int to, nxt; }e[maxn]; int head[maxn], tot = 0; void addedge(int u, int v){ e[++tot].to = v, e[tot].nxt = head[u]; head[u] = tot; } int f[maxn], son[maxn], sz[maxn], dep[maxn]; void dfs1(int cur, int fa){ f[cur] = fa; sz[cur] = 1; dep[cur] = dep[fa] + 1; int Max = -1; for (int i = head[cur]; i; i = e[i].nxt){ int v = e[i].to; dfs1(v, cur); sz[cur] += sz[v]; if (Max < sz[v]) Max = sz[v], son[cur] = v; } } int top[maxn], id[maxn], tdx = 0; void dfs2(int cur, int topf){ top[cur] = topf; id[cur] = ++tdx; if (!son[cur]) return; dfs2(son[cur], topf); for (int i = head[cur]; i; i = e[i].nxt) if (e[i].to != son[cur]) dfs2(e[i].to, e[i].to); } int n, m, Q, c[maxn], b[maxn], C; LL _abs(LL x){return x < 0 ? -x : x;} struct T{ struct A{ int ls, rs; LL v, v2, tg; }a[maxn * 200]; int ttot; #define LS a[a[cur].ls] #define RS a[a[cur].rs] void pushdown(int cur, int l, int r){ if (a[cur].tg == 0) return; int mid = l + r >> 1; if (a[cur].ls == 0) a[cur].ls = ++ttot; LS.v2 += 2ll * a[cur].tg * LS.v + 1ll * a[cur].tg * a[cur].tg * (mid - l + 1); LS.v += 1ll * a[cur].tg * (mid - l + 1); if (a[cur].rs == 0) a[cur].rs = ++ttot; RS.v2 += 2ll * a[cur].tg * RS.v + 1ll * a[cur].tg * a[cur].tg * (r - mid); RS.v += 1ll * a[cur].tg * (r - mid); LS.tg += a[cur].tg; RS.tg += a[cur].tg; a[cur].tg = 0; } void upd(int &cur, int l, int r, int L, int R, int k){ if (l > R || r < L) return; if (!cur) cur = ++ttot; if (l >= L && r <= R){ a[cur].v2 += 2ll * k * a[cur].v + 1ll * (r - l + 1) * k * k; a[cur].v += 1ll * k * (r - l + 1); a[cur].tg += k; return; } pushdown(cur, l, r); int mid = l + r >> 1; upd(a[cur].ls, l, mid, L, R, k); upd(a[cur].rs, mid + 1, r, L, R, k); a[cur].v = LS.v + RS.v; a[cur].v2 = LS.v2 + RS.v2; } }t; void urange(int col, int u, int v, int k){ while (top[u] != top[v]){ if (dep[top[u]] > dep[top[v]]) swap(u, v); t.upd(col, 1, n, id[top[v]], id[v], k); v = f[top[v]]; } if (dep[u] > dep[v]) swap(u, v); t.upd(col, 1, n, id[u], id[v], k); } LL sdep[maxn]; signed main(){ scanf("%lld%lld%lld%lld", &n, &m, &Q, &C); t.ttot = m; for (int i = 1; i <= n; i++) scanf("%lld", c + i); for (int fa, i = 2; i <= n; i++) scanf("%lld", &fa), addedge(fa, i); for (int i = 1; i <= m; i++) scanf("%lld", b + i); dfs1(1, 0); dfs2(1, 1); for (int i = 1; i <= n; i++) urange(c[i], 1, i, 1), sdep[c[i]] += dep[i]; while (Q--){ int opt, x, y; scanf("%lld", &opt); if (opt == 1){ scanf("%lld%lld", &x, &y);
urange(c[x], 1, x, -1); sdep[c[x]] -= dep[x]; urange(c[x] = y, 1, x, 1); sdep[c[x]] += dep[x]; } if (opt == 2){ scanf("%lld", &x); double ans = C * C; ans += 1.0 * b[x] * b[x] / n * t.a[x].v2; ans -= 2.0 * C * b[x] / n * sdep[x]; printf("%.8lf\n", ans); }
} return 0; }
|